//
//  CompositeObjects.m
//  Charles
//
//  Created by Charles on 2017/7/9.
//  Copyright © 2017年 charles. All rights reserved.
//

#import "CompositeObjects.h"
#import "IteratorProtocal.h"

@implementation CMenuItem {
    NSString *_name;
    NSString *_desc;
    BOOL _vegetarian;
    double _price;
}

- (instancetype)initWithName:(NSString *)name desc:(NSString *)desc vegetarian:(BOOL)vegetarian price:(double)price {
    if (self = [super init]) {
        _name = name;
        _desc = desc;
        _vegetarian = vegetarian;
        _price = price;
    }
    return self;
}

- (CGFloat)getPrice {
    return _price;
}

- (NSString *)getDesc {
    return _desc;
}

- (NSString *)getName {
    return _name;
}

- (BOOL)isVegetarian {
    return _vegetarian;
}

- (id<Iterator>)createIterator {
    return nil;
}

- (void)print {
    NSMutableString *menu = [[NSMutableString alloc]initWithCapacity:0];
    [menu appendFormat:@" %@",self.getName];
    if ([self isVegetarian]) {
        [menu appendFormat:@"(v)"];
    }
    [menu appendFormat:@" %f",self.getPrice];
    [menu appendFormat:@" %@",self.getDesc];
    
    NSLog(@"%@",menu);
}

@end

@interface CMenu ()

@property (nonatomic,strong) NSMutableArray *menuCompontents;

@end

@implementation CMenu {
    NSString *_name;
    NSString *_desc;
}

- (instancetype)initWithName:(NSString *)name desc:(NSString *)desc {
    if (self = [super init]) {
        _name = name;
        _desc = desc;
        self.menuCompontents = [[NSMutableArray alloc]initWithCapacity:0];
    }
    return self;
}

- (void)addComponent:(id<MenuComponent>)component {
    [self.menuCompontents addObject:component];
}

- (void)removeComponent:(id<MenuComponent>)component {
    if ([self.menuCompontents containsObject:component]) {
        [self.menuCompontents removeObject:component];
    }
}

- (id<MenuComponent>)getChild:(NSInteger)index {
    if (index > self.menuCompontents.count) {
        return nil;
    }
    return (id<MenuComponent>)[self.menuCompontents objectAtIndex:index];
}

- (NSString *)getName {
    return _name;
}

- (NSString *)getDesc {
    return _desc;
}

- (id<Iterator>)createIterator {
    return [[CompositeIterator alloc]initWithIterators:_menuCompontents];
}

- (void)print {
    NSLog(@"%@, %@",[self getName],[self getDesc]);
    NSLog(@"------------");
    
    for (id<MenuComponent>menuComponent in self.menuCompontents) {
        [menuComponent print];
    }
}

@end

@implementation CompositeIterator {
    NSMutableArray *_stack;
}

- (instancetype)initWithIterators:(NSArray *)iterators {
    if (self = [super init]) {
        _stack = [[NSMutableArray alloc]initWithCapacity:0];
        [_stack addObjectsFromArray:iterators];
    }
    return self;
}

- (id)next {
    if ([self hasNext]) {
        id<Iterator>iterator = _stack.lastObject;
        id<MenuComponent>component = (id<MenuComponent>)iterator.next;
        if ([component isKindOfClass:[CMenu class]]) {
            [_stack addObject:[component createIterator]];
        }
        return component;
    }else {
        return nil;
    }
}

- (BOOL)hasNext {
    if (_stack.count == 0) {
        return NO;
    }else {
        id<MenuComponent>component = (id<MenuComponent>)_stack.lastObject;
        id<Iterator>iterator = (id<Iterator>)[component createIterator];
        if (![iterator hasNext]) {
            [_stack removeLastObject];
            return [self hasNext];
        }else {
            return YES;
        }
    }
    return NO;
}

- (void)remove {
    
}


@end


@interface CWaitress ()

@property (strong,nonatomic) id<MenuComponent>allMenus;

@end

@implementation CWaitress

- (instancetype)initWithAllMenus:(id<MenuComponent>)allMenus {
    if (self = [super init]) {
        self.allMenus = allMenus;
    }
    return self;
}

- (void)printMenu {
    [self.allMenus print];
}

- (void)printVegetarianMenu {
    id<Iterator> iterator = (CompositeIterator *)[self.allMenus createIterator];
    NSLog(@"VEGERARIAN MENU--------");
    while ([iterator hasNext]) {
        id<MenuComponent> menuComponent = (id<MenuComponent>)[iterator next];
        @try {
            if ([menuComponent isVegetarian]) {
                [menuComponent print];
            }
        } @catch (NSException *exception) {
            NSLog(@"exception is %@",exception);
        }
    }
}

@end




